﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Physis.Enterprise {

    public class Environment : Core.CoreConfigurationObject {
        
        #region Private Properties

        private Data.DatabaseConfiguration databaseConfiguration = new Data.DatabaseConfiguration ();

        #endregion 


        #region Public Properties

        public Data.DatabaseConfiguration DatabaseConfiguration { get { return databaseConfiguration; } set { databaseConfiguration = value; } }

        #endregion 

        
        #region Constructors

        public Environment (Application forApplication) : base (forApplication) {

            return;

        }

        public Environment (Application forApplication, Int64 forId) : base (forApplication) {

            if (!Load (forId, Application.EnterpriseDatabase)) {

                throw new Exception (GetType ().FullName + ".Load [Failed]: " + forId);

            }

            return;

        }

        public Environment (Application forApplication, String forName) : base (forApplication) {

            if (!Load (forName, Application.EnterpriseDatabase)) {

                throw new Exception (GetType ().FullName + ".Load [Failed]: " + forName);

            }

            return;

        }

        #endregion


        #region Database Functions

        protected override Dictionary<String, String> Validate () {

            Dictionary<String, String> validationErrors = base.Validate ();


            if (String.IsNullOrWhiteSpace (databaseConfiguration.ServerName)) { validationErrors.Add ("Server Name", "Empty or invalid value for Server Name."); }

            if (String.IsNullOrWhiteSpace (databaseConfiguration.DatabaseName)) { validationErrors.Add ("Database Name", "Empty or invalid value for Database Name."); }


            if ((String.IsNullOrWhiteSpace (databaseConfiguration.DatabaseName)) && (!databaseConfiguration.TrustedConnection)) { validationErrors.Add ("User Name", "Empty or invalid value for User Name."); }


            return validationErrors;

        }

        public override void MapDataFields (System.Data.DataRow currentRow) {
            
            base.MapDataFields (currentRow);


            databaseConfiguration.DatabaseType = (Data.Enumerations.DatabaseType)Data.Readers.DataReader.Int32FromDatabase (currentRow, "DatabaseType");

            databaseConfiguration.ServerName = Data.Readers.DataReader.StringFromDatabase (currentRow, "ServerName");

            databaseConfiguration.DatabaseName = Data.Readers.DataReader.StringFromDatabase (currentRow, "DatabaseName");

            databaseConfiguration.PoolingEnabled = Data.Readers.DataReader.BooleanFromDatabase (currentRow, "PoolingEnabled");

            databaseConfiguration.PoolSizeMinimum = Data.Readers.DataReader.Int32FromDatabase (currentRow, "PoolSizeMinimum");

            databaseConfiguration.PoolSizeMaximum = Data.Readers.DataReader.Int32FromDatabase (currentRow, "PoolSizeMaximum");

            databaseConfiguration.TrustedConnection = Data.Readers.DataReader.BooleanFromDatabase (currentRow, "TrustedConnection");

            databaseConfiguration.UserName = Data.Readers.DataReader.StringFromDatabase (currentRow, "UserName");

            databaseConfiguration.Password = Data.Readers.DataReader.StringFromDatabase (currentRow, "Password");

            databaseConfiguration.CustomAttributes = Data.Readers.DataReader.StringFromDatabase (currentRow, "CustomAttributes");

            return;

        }

        public override Boolean Save () {

            Boolean success = false;

            try {

                Dictionary<String, String> validationErrors = Validate ();

                if (validationErrors.Count > 0) {

                    Application.SetLastException (new Exception ("Invalid [" + validationErrors.Keys.First () + "]: " + validationErrors.Values.First ()));

                    return false;

                }

                UpdateModifiedToSessionUser ();


                System.Data.IDbCommand command = Application.EnterpriseDatabase.CreateCommand (ObjectType + "_InsertUpdate");

                command.CommandType = System.Data.CommandType.StoredProcedure;


                Application.EnterpriseDatabase.AppendCommandParameter (command, "Id", Id);

                Application.EnterpriseDatabase.AppendCommandParameter (command, "Name", Name, 60);

                Application.EnterpriseDatabase.AppendCommandParameter (command, "Description", Description, 999);


                Application.EnterpriseDatabase.AppendCommandParameter (command, "DatabaseType", ((Int32)DatabaseConfiguration.DatabaseType));

                Application.EnterpriseDatabase.AppendCommandParameter (command, "ServerName", DatabaseConfiguration.ServerName, 60);

                Application.EnterpriseDatabase.AppendCommandParameter (command, "DatabaseName", DatabaseConfiguration.DatabaseName, 60);

                Application.EnterpriseDatabase.AppendCommandParameter (command, "PoolingEnabled", DatabaseConfiguration.PoolingEnabled);

                Application.EnterpriseDatabase.AppendCommandParameter (command, "PoolSizeMinimum", DatabaseConfiguration.PoolSizeMinimum);

                Application.EnterpriseDatabase.AppendCommandParameter (command, "PoolSizeMaximum", DatabaseConfiguration.PoolSizeMaximum);

                Application.EnterpriseDatabase.AppendCommandParameter (command, "TrustedConnection", DatabaseConfiguration.TrustedConnection);

                Application.EnterpriseDatabase.AppendCommandParameter (command, "UserName", DatabaseConfiguration.UserName, 60);

                Application.EnterpriseDatabase.AppendCommandParameter (command, "Password", DatabaseConfiguration.Password, 60);

                Application.EnterpriseDatabase.AppendCommandParameter (command, "CustomAttributes", DatabaseConfiguration.CustomAttributes, 60);


                Application.EnterpriseDatabase.AppendCommandParameter (command, "ModifiedId", Application.Session.UserAccountName, 60);

                success = (command.ExecuteNonQuery () > 0);

                if (success) { SetIdentity (Application.EnterpriseDatabase); }

            }

            catch (Exception exception) {

                success = false;

                Application.SetLastException (exception);

            }

            return success;

        }

        public override Boolean Delete () {

            return base.DeleteFromDatabase (DeleteStatementById (), Application.EnterpriseDatabase);

        }

        #endregion 


    }

}
